
package org.zz.tool;

public class mxJavaBase64 {
    public mxJavaBase64() {
    }

    public static int JavaBase64Encode(byte[] pInput, int inputLen, byte[] pOutput, int outputbufsize) {
        boolean currentin = false;
        boolean currentin3 = false;
        String codebuffer = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
        byte[] encodingTable = new byte[65];
        encodingTable = codebuffer.getBytes();
        int outlen = (inputLen + 2) / 3 * 4;
        int modulus = inputLen % 3;
        int datalen = inputLen - modulus;
        int encodedatalen = datalen * 4 / 3;
        if(outputbufsize < outlen) {
            return 0;
        } else {
            int i;
            int j;
            long ltmp;
            int currentin2;
            int currentin21;
            switch(modulus) {
                case 0:
                default:
                    break;
                case 1:
                    i = inputLen - 1;
                    j = outlen - 4;
                    currentin2 = pInput[i];
                    if(currentin2 < 0) {
                        currentin2 += 256;
                    }

                    ltmp = (long)currentin2 << 16;
                    pOutput[j] = encodingTable[(int)(ltmp >> 18 & 63L)];
                    pOutput[j + 1] = encodingTable[(int)(ltmp >> 12 & 63L)];
                    pOutput[j + 2] = 61;
                    pOutput[j + 3] = 61;
                    break;
                case 2:
                    i = inputLen - 2;
                    j = outlen - 4;
                    byte currentin1 = pInput[i];
                    currentin21 = pInput[i + 1];
                    if(currentin1 < 0) {
                        currentin2 = currentin1 + 256;
                    }

                    if(currentin21 < 0) {
                        currentin21 += 256;
                    }

                    ltmp = (long)pInput[i] << 16 | (long)currentin21 << 8;
                    pOutput[j] = encodingTable[(int)(ltmp >> 18 & 63L)];
                    pOutput[j + 1] = encodingTable[(int)(ltmp >> 12 & 63L)];
                    pOutput[j + 2] = encodingTable[(int)(ltmp >> 6 & 63L)];
                    pOutput[j + 3] = 61;
            }

            i = datalen - 3;

            for(j = encodedatalen - 4; i >= 0; j -= 4) {
                currentin2 = pInput[i];
                currentin21 = pInput[i + 1];
                int currentin31 = pInput[i + 2];
                if(currentin2 < 0) {
                    currentin2 += 256;
                }

                if(currentin21 < 0) {
                    currentin21 += 256;
                }

                if(currentin31 < 0) {
                    currentin31 += 256;
                }

                ltmp = (long)currentin2 << 16 | (long)currentin21 << 8 | (long)currentin31;
                pOutput[j] = encodingTable[(int)(ltmp >> 18 & 63L)];
                pOutput[j + 1] = encodingTable[(int)(ltmp >> 12 & 63L)];
                pOutput[j + 2] = encodingTable[(int)(ltmp >> 6 & 63L)];
                pOutput[j + 3] = encodingTable[(int)(ltmp & 63L)];
                i -= 3;
            }

            return outlen;
        }
    }

    public static int JavaBase64Decode(byte[] pInput, int inputLen, byte[] pOutput) {
        short np = 255;
        char[] decodingTable = new char[256];

        int i;
        for(i = 0; i < 256; ++i) {
            decodingTable[i] = (char)np;
        }

        for(i = 65; i <= 90; ++i) {
            decodingTable[i] = (char)(i - 65);
        }

        for(i = 97; i <= 122; ++i) {
            decodingTable[i] = (char)(i - 97 + 26);
        }

        for(i = 48; i <= 57; ++i) {
            decodingTable[i] = (char)(i - 48 + 52);
        }

        decodingTable[43] = 62;
        decodingTable[47] = 63;
        if(inputLen % 4 != 0) {
            return 0;
        } else {
            byte padnum;
            if(pInput[inputLen - 2] == 61) {
                padnum = 2;
            } else if(pInput[inputLen - 1] == 61) {
                padnum = 1;
            } else {
                padnum = 0;
            }

            int outlen = inputLen / 4 * 3 - padnum;
            int datalen = (inputLen - padnum) / 4 * 3;
            i = 0;

            int m;
            long ltmp;
            char ctmp;
            for(int j = 0; i < datalen; j += 4) {
                ltmp = 0L;

                for(m = j; m < j + 4; ++m) {
                    ctmp = decodingTable[pInput[m]];
                    if(ctmp == np) {
                        return 0;
                    }

                    ltmp = ltmp << 6 | (long)ctmp;
                }

                pOutput[i] = (byte)((int)(ltmp >> 16 & 255L));
                pOutput[i + 1] = (byte)((int)(ltmp >> 8 & 255L));
                pOutput[i + 2] = (byte)((int)(ltmp & 255L));
                i += 3;
            }

            switch(padnum) {
                case 0:
                default:
                    break;
                case 1:
                    ltmp = 0L;

                    for(m = inputLen - 4; m < inputLen - 1; ++m) {
                        ctmp = decodingTable[pInput[m]];
                        if(ctmp == np) {
                            return 0;
                        }

                        ltmp = ltmp << 6 | (long)ctmp;
                    }

                    ltmp <<= 6;
                    pOutput[outlen - 2] = (byte)((int)(ltmp >> 16 & 255L));
                    pOutput[outlen - 1] = (byte)((int)(ltmp >> 8 & 255L));
                    break;
                case 2:
                    ltmp = 0L;

                    for(m = inputLen - 4; m < inputLen - 2; ++m) {
                        ctmp = decodingTable[pInput[m]];
                        if(ctmp == np) {
                            return 0;
                        }

                        ltmp = ltmp << 6 | (long)ctmp;
                    }

                    ltmp <<= 12;
                    pOutput[outlen - 1] = (byte)((int)(ltmp >> 16 & 255L));
            }

            return outlen;
        }
    }
}
